<?php


namespace app\controller\api;


use app\common\service\redis\PoolRedis;
use app\common\service\sms\AliSms;
use app\model\AdminStaff;
use app\model\AdminStaffData;
use app\model\AdminVolunteer;
use app\util\ReturnCode;
use app\util\Strs;
use app\util\Tools;
use think\facade\Cache;
use think\facade\Log;
use think\facade\Queue;
use think\facade\Validate;
use think\Response;

class Passport extends Base
{

    /**
     * @brief APP账号密码登录
     * @method POST
     * @return Response
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @Time: 2021/12/2 15:24
     */
    public function login() : Response {
        $username = $this->request->post('username');
        $password = $this->request->post('password');
        $device_id = $this->request->post('device_id/s', '');
        $device_name = $this->request->post('device_name/s', '');
        $appversion = $this->request->header('appversion', '');
        if (!$username) {
            return $this->buildFailed(ReturnCode::LOGIN_ERROR, '缺少用户名!');
        }
        if (!$password) {
            return $this->buildFailed(ReturnCode::LOGIN_ERROR, '缺少密码!');
        } else {
            $password = Tools::userMd5($password);
        }

        $staff = (new AdminStaff())::where('phone', $username)->where('password', $password)->where('is_delete', 0)->find();
        if ($staff) {
            if ($staff->type == 0 && $staff->expire_flag) {
                return $this->buildFailed(ReturnCode::AUTH_ERROR, '账号已过期，无法登录');
            }
            if ($staff->status == 1) {
                //更新用户数据
                $staffData = $staff->staffData;
                $data = [];
                if ($staffData) {
                    if (in_array($staffData->bind_device_status, [1, 2]) && $device_id && $staffData->last_login_device_id && $device_id != $staffData->last_login_device_id) {
                        return $this->buildFailed(ReturnCode::LOGIN_ERROR, '账号与绑定手机不符');
                    }
                    $staffData->login_times++;
                    $staffData->last_login_ip = sprintf("%u", ip2long($this->request->ip()));
                    $staffData->last_login_time = time();
                    $staffData->app_version = $appversion;
                    if (!in_array($staffData->bind_device_status, [1, 2]) && $device_id) {
                        $staffData->last_login_device_id = $device_id;
                        $staffData->last_login_device_name = $device_name;
                        $staffData->bind_device_status = 1;
                        $staffData->last_bind_device_time = time();
                    }
                    $staffData->save();
                } else {
                    $data['login_times'] = 1;
                    $data['staff_id'] = $staff->id;
                    $data['last_login_ip'] = sprintf("%u", ip2long($this->request->ip()));
                    $data['last_login_time'] = time();
                    $data['app_version'] = $appversion;
                    if ($device_id) {
                        $data['last_login_device_id'] = $device_id;
                        $data['last_login_device_name'] = $device_name;
                        $data['bind_device_status'] = 1;
                        $data['last_bind_device_time'] = time();
                    }
                    AdminStaffData::create($data);
                }
            } elseif ($staff->status == 2) {
                return $this->buildFailed(ReturnCode::AUDIT_FAILED, '账号审核拒绝', [
                    'refuse_reason' => $staff->refuse_reason
                ]);
            } else {
                return $this->buildFailed(ReturnCode::AUDIT_WAITING, '账号审核中');
            }
        } else {
            return $this->buildFailed(ReturnCode::LOGIN_ERROR, '账号密码不正确');
        }
        // 保存登录成功设备,30天
        $redis = PoolRedis::instance();
        $log_device_id = $redis->get('deviceUUID:staff'.$staff->id);
        // 已登录的设备下线,并且重新生成uuid
        if ($log_device_id && $device_id && $log_device_id != $device_id) {
            $redis->set('deviceUUID:staff'.$staff->uuid, 'offline');
            $staff->uuid = substr(Strs::uuid(), 1, -1);
            $staff->save();
        }
        // 更新登录信息
        $redis->set('deviceUUID:staff'.$staff->uuid, 'online', 30*86400);
        if ($device_id) {
            $redis->set('deviceUUID:staff'.$staff->id, $device_id, 30*86400);
        }

        // sim卡调用获取seid,即sim_uid
        Queue::push('app\task\job\SyncPhoneSeidJob@fire', [
            'phone'=> $staff->phone
        ]);
        return $this->buildSuccess([
            'uuid' => $staff->uuid
        ], '登录成功');
    }

    /**
     * @func captchaLogin
     * @method POST
     * @desc 验证码登录
     * @return Response
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @Time: 2021/12/7 11:07
     */
    public function captchaLogin() : Response {
        $phone  = input('post.phone');
        $code  = input('post.code/d');
        $device_id  = input('post.device_id/s', '');
        $device_name  = input('post.device_name/s', '');
        $appversion = $this->request->header('appversion', '');
        if (empty($phone) || !validatePhone($phone)) {
            return $this->buildFailed(ReturnCode::PARAM_INVALID, '请输入正确的手机号');
        }
        // 临时将验证码固定为 123456
        // if (!AliSms::check($phone, $code)) {
        //     return $this->buildFailed(ReturnCode::RECORD_NOT_FOUND, '验证码错误');
        // }
        if ($code != '123456') {
            return $this->buildFailed(ReturnCode::RECORD_NOT_FOUND, '验证码错误');
        }
        $staff = (new AdminStaff())->where('phone', $phone)->where('is_delete', 0)->find();
        if (!$staff) {
            return $this->buildFailed(ReturnCode::NOT_EXISTS, '账号不存在');
        }
        if ($staff->type == 0 && $staff->expire_flag) {
            return $this->buildFailed(ReturnCode::AUTH_ERROR, '账号已过期，无法登录');
        }
        if ($staff->status == 1) {
            //更新用户数据
            $staffData = $staff->staffData;
            $data = [];
            if ($staffData) {
                // 临时放通不处理设备限制
                if (!in_array($phone, ['17620729860', '16620363310'])){
                    // 判断设备ID
//                    if (in_array($staffData->bind_device_status, [1, 2]) && $device_id && $staffData->last_login_device_id && $device_id != $staffData->last_login_device_id) {
//                        return $this->buildFailed(ReturnCode::LOGIN_ERROR, '账号与绑定手机不符');
//                    }
                    // 判断设备名
                    if (in_array($staffData->bind_device_status, [1, 2]) && $device_name && $staffData->last_login_device_name && $device_name != $staffData->last_login_device_name) {
                        return $this->buildFailed(ReturnCode::LOGIN_ERROR, '账号与绑定手机不符');
                    }
                }
                $staffData->login_times++;
                $staffData->last_login_ip = sprintf("%u", ip2long($this->request->ip()));
                $staffData->last_login_time = time();
                $staffData->app_version = $appversion;
                if (!in_array($staffData->bind_device_status, [1, 2]) && $device_id) {
                    $staffData->last_login_device_id = $device_id;
                    $staffData->last_login_device_name = $device_name;
                    $staffData->bind_device_status = 1;
                    $staffData->last_bind_device_time = time();
                }
                $staffData->save();
            } else {
                $data['login_times'] = 1;
                $data['staff_id'] = $staff->id;
                $data['last_login_ip'] = sprintf("%u", ip2long($this->request->ip()));
                $data['last_login_time'] = time();
                $data['app_version'] = $appversion;
                if ($device_id) {
                    $data['last_login_device_id'] = $device_id;
                    $data['last_login_device_name'] = $device_name;
                    $data['bind_device_status'] = 1;
                    $data['last_bind_device_time'] = time();
                }
                AdminStaffData::create($data);
            }

            // 保存登录成功设备,30天
            $redis = PoolRedis::instance();
            $log_device_id = $redis->get('deviceUUID:staff'.$staff->id);
            // 已登录的设备下线,并且重新生成uuid
            if ($log_device_id && $device_id && $log_device_id != $device_id) {
                $redis->set('deviceUUID:staff'.$staff->uuid, 'offline');
                $staff->uuid = substr(Strs::uuid(), 1, -1);
                $staff->save();
            }
            // 更新登录信息
            $redis->set('deviceUUID:staff'.$staff->uuid, 'online', 30*86400);
            if ($device_id) {
                $redis->set('deviceUUID:staff'.$staff->id, $device_id, 30*86400);
            }

            // sim卡调用获取seid,即sim_uid
            Queue::push('app\task\job\SyncPhoneSeidJob@fire', [
                'phone'=> $staff->phone
            ]);
            return $this->buildSuccess([
                'uuid' => $staff->uuid
            ], '登录成功');
        } elseif ($staff->status == 2) {
            return $this->buildFailed(ReturnCode::AUDIT_FAILED, '账号审核拒绝', [
                'refuse_reason' => $staff->refuse_reason,
                'uuid' => $staff->uuid
            ]);
        } else {
            return $this->buildFailed(ReturnCode::AUDIT_WAITING, '账号审核中');
        }
    }


    /**
     * @func modifyPhone
     * @method POST
     * @desc 修改手机号
     * @return response
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @Time: 2021/12/7 10:55
     */
    public function modifyPhone() : Response {
        $username  = input('post.username');
        $code  = input('post.code/d');
        $phone  = input('post.phone');
        $phoneCode  = input('post.phoneCode/d');
        if (empty($phone) || !validatePhone($username) || !validatePhone($phone)) {
            return $this->buildFailed(ReturnCode::PARAM_INVALID, '请输入正确的手机号');
        }
        if (!AliSms::check($username, $code) || !AliSms::check($phone, $phoneCode)) {
            return $this->buildFailed(ReturnCode::RECORD_NOT_FOUND, '验证码错误');
        }
        $staff = (new AdminStaff())->where('phone', $username)->where('is_delete', 0)->find();
        if (!$staff) {
            return $this->buildFailed(ReturnCode::RECORD_NOT_FOUND, '账号不存在');
        }
        $staff->phone = $phone;
        $staff->save();

        Cache::delete("code_cache".$username);
        Cache::delete("code_cache".$phone);

        // 删除记录
        $redis = PoolRedis::instance();
        $redis->delete('deviceUUID:staff'.$staff->uuid);
        $redis->delete('deviceUUID:staff'.$staff->id);
        return $this->buildSuccess([], '手机号修改成功，请重新登录');
    }

    /**
     * @func modifyPassword
     * @method POST
     * @desc 修改密码
     * @return Response
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @Time: 2021/12/6 18:46
     */
    public function modifyPassword() : Response {
        $phone  = input('post.phone');
        $code  = input('post.code/d');
        $password  = input('post.password');
        $confirm  = input('post.password_confirm');
        if (empty($phone) || !validatePhone($phone)) {
            return $this->buildFailed(ReturnCode::PARAM_INVALID, '请输入正确的手机号');
        }
        if ($password != $confirm) {
            return $this->buildFailed(ReturnCode::NUMBER_MATCH_ERROR, '输入的新密码不一致');
        }
        if (!AliSms::check($phone, $code)) {
            return $this->buildFailed(ReturnCode::RECORD_NOT_FOUND, '验证码错误');
        }
        $staff = (new AdminStaff())->where('phone', $phone)->where('is_delete', 0)->find();
        if (!$staff) {
            return $this->buildFailed(ReturnCode::RECORD_NOT_FOUND, '账号不存在');
        }
        $staff->password = Tools::userMd5($password);
        $staff->save();

        Cache::delete("code_cache".$phone);
        // 删除记录
        $redis = PoolRedis::instance();
        $redis->delete('deviceUUID:staff'.$staff->uuid);
        $redis->delete('deviceUUID:staff'.$staff->id);
        return $this->buildSuccess([], '密码修改成功，请重新登录');
    }

    /**
     * @func uploadHeader
     * @method POST
     * @desc 更改头像
     * @return Response
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @Time: 2021/12/6 18:46
     */
    public function uploadHeader() : Response {
        $avatar_url  = input('post.avatar_url');
        $uuid  = input('post.uuid');
        if (empty($avatar_url)) {
            return $this->buildFailed(ReturnCode::PARAM_INVALID, '头像上传失败');
        }
        $staff = (new AdminStaff())->where('uuid', $uuid)->where('is_delete', 0)->find();
        if (!$staff) {
            return $this->buildFailed(ReturnCode::RECORD_NOT_FOUND, '账号不存在');
        }
        $staff->avatar_url = $avatar_url;
        $staff->save();

        return $this->buildSuccess([], '头像上传成功');
    }

    public function logout(): Response {
        $data = input('get.');
        $validate = Validate::rule([
            'uuid|用户标识' => 'require',
        ]);
        if (!$validate->check($data)) {
            return $this->buildFailed(ReturnCode::PARAM_INVALID, $validate->getError());
        }
        $staff = (new AdminStaff())->where('uuid', $data['uuid'])->where('is_delete', 0)->find();
        if (!$staff) {
            return $this->buildFailed(ReturnCode::RECORD_NOT_FOUND, '账号不存在');
        }
        // 删除记录
        $redis = PoolRedis::instance();
        $redis->delete('deviceUUID:staff'.$staff->uuid);
        $redis->delete('deviceUUID:staff'.$staff->id);
        return $this->buildSuccess([], '注销成功');
    }

}